﻿/*
    工具类
    功能：查找物体   读写文本文件Json，Txt, Csv
 */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Text;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using System.Diagnostics;
using System;
using Debug = UnityEngine.Debug;
using System.Net;
using System.Security.Cryptography;
using UnityEngine.UI;

public class ToolUnity
{
    /// <summary>
    /// 通过名字查找子物体
    /// </summary>
    /// <param name="parent">自身</param>
    /// <param name="childName"></param>
    /// <returns></returns>
    public static GameObject FindGameObject(GameObject parent, string childName)
    {
        if (parent.name == childName)
        {
            return parent;
        }

        if (parent.transform.childCount < 1)
        {
            return null;
        }

        GameObject obj = null;
        for (int i = 0; i < parent.transform.childCount; i++)
        {
            GameObject go = parent.transform.GetChild(i).gameObject;
            obj = FindGameObject(go, childName);
            if (obj != null)
            {
                break;
            }
        }
        return obj;
    }

    /// <summary>
    /// 获取文件的MD5码
    /// </summary>
    /// <param name="filepath"></param>
    /// <returns></returns>
    public static string GetFileMD5(string filepath)
    {
        FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read);
        int bufferSize = 1048576;
        byte[] buff = new byte[bufferSize];
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
        md5.Initialize();
        long offset = 0;
        while (offset < fs.Length)
        {
            long readSize = bufferSize;
            if (offset + readSize > fs.Length)
                readSize = fs.Length - offset;
            fs.Read(buff, 0, Convert.ToInt32(readSize));
            if (offset + readSize < fs.Length)
                md5.TransformBlock(buff, 0, Convert.ToInt32(readSize), buff, 0);
            else
                md5.TransformFinalBlock(buff, 0, Convert.ToInt32(readSize));
            offset += bufferSize;
        }
        if (offset >= fs.Length)
        {
            fs.Close();
            byte[] result = md5.Hash;
            md5.Clear();
            StringBuilder sb = new StringBuilder(32);
            for (int i = 0; i < result.Length; i++)
                sb.Append(result[i].ToString("X2"));
            return sb.ToString();
        }
        else
        {
            fs.Close();
            return null;
        }
    }

    /// <summary>
    /// 读取文本返回string类型的内容
    /// </summary>
    /// <param name="jsonFileName">文件名</param>
    public static string ReadTxtToString(string path)
    {
        if (File.Exists(path))
        {
            FileInfo fileInfo = new FileInfo(path);
            StreamReader streamReader = fileInfo.OpenText();
            string str = streamReader.ReadToEnd();
            streamReader.Close();               //文件流释放
            streamReader.Dispose();
            return str;
        }
        else
        {
            UnityEngine.Debug.Log("路径或名字错误！！");
            return default(string);
        }
    }

    /// <summary>
    ///  /*为eventTrigger添加事件(参数1:添加事件的物体;参数2:事件类型;参数3:需要调用的事件函数)*/
    /// </summary>
    /// <param name="obj">添加事件的物体</param>
    /// <param name="eventType">事件类型</param>
    /// <param name="myFunction">需要调用的事件函数</param>
    public static void AddEventTrigger(GameObject obj, EventTriggerType eventType, UnityAction<BaseEventData> myFunction)//泛型委托
    {
        EventTrigger eventTri = obj.GetComponent<EventTrigger>();
        if (eventTri == null)
        {
            eventTri = obj.AddComponent<EventTrigger>();
        }
        EventTrigger.Entry entry = new EventTrigger.Entry();
        entry.eventID = eventType;
        entry.callback.AddListener(myFunction);
        eventTri.triggers.Add(entry);
    }

    /// <summary>
	/// 运行exe 程序
	/// </summary>
	public static void ReStartProcess(string ProcessPath)
    {
        try
        {
            Process p = new Process();
            string fileName = ProcessPath;
            p.Start();
        }
        catch (Exception e)
        {
            Debug.LogError(e);
        }
    }

    /// <summary>
    ///写入Json数据到文件 不支持移动端
    /// </summary>
    /// <param name="jsonFileName"></param>
    /// <param name="data"></param>
    public static void WriteStringToJson(string path, string jsonFileName, string data)
    {
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);  //创建文件夹
        }
        if (File.Exists(path + "/" + jsonFileName))
        {
            File.WriteAllText(path + "/" + jsonFileName, data);
            Debug.Log("有文件修改成功");
        }
        else
        {
            FileStream fs = new FileStream(path + "/" + jsonFileName, FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter m_streamWriter = new StreamWriter(fs, Encoding.UTF8);   //UTF8格式写入
            m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
            m_streamWriter.WriteLine(data);
            m_streamWriter.Flush();
            m_streamWriter.Close();
        }
    }

    /// <summary>
    /// 获取所有子物体
    /// </summary>
    /// <param name="transform"></param>
    /// <returns></returns>
    public static List<GameObject> GetAllChildGameObject(Transform transform)
    {
        List<GameObject> gameObjects = new List<GameObject>();
        Transform[] father = transform.GetComponentsInChildren<Transform>();
        for (int i = 0; i < father.Length; i++)
        {
            gameObjects.Add(father[i].gameObject);
        }
        Debug.Log("成功获取所有子物体");
        return gameObjects;
    }

    /// 删除物体同时清空物体所带数据
    /// </summary>
    /// <param name="obj"></param>
    public static void Destroy(UnityEngine.Object obj)
    {
        GameObject.Destroy(obj);
        Resources.UnloadUnusedAssets();
    }

    //计时器
    public static void WaitTime(float Time, UnityAction action)
    {
        EzMonoManager.Instance.StartCoroutine(IETimeClick(Time, action));
    }

    static IEnumerator IETimeClick(float time, UnityAction action)
    {
        yield return new WaitForSeconds(time);
        action();
    }
   
    public static bool IsMouseInUI(GraphicRaycaster _raycaster)
    {
        PointerEventData data = new PointerEventData(EventSystem.current);

        data.pressPosition = Input.mousePosition;

        data.position = Input.mousePosition;

        List<RaycastResult> results = new List<RaycastResult>();
        _raycaster.Raycast(data,results);
        return results.Count>0;
    }

    /// <summary>
    /// 查找文件夹下所有文件
    /// </summary>
    /// <param name="filePathByForeach"></param>
    /// <returns></returns>
    public static void ForeachFile(string filePathByForeach,string type,Action<List<string>> action)
    {
        List<string> tempList = new List<string>();
        try
        {
            DirectoryInfo theFolder = new DirectoryInfo(filePathByForeach);
            DirectoryInfo[] dirInfo = theFolder.GetDirectories();//获取所在目录的文件夹
            FileInfo[] file = theFolder.GetFiles();//获取所在目录的文件
            foreach (FileInfo fileItem in file) //遍历文件
            {
                string[] vs = fileItem.FullName.Split('.');
                if (vs.Length>=2)
                {
                    if (vs[vs.Length-1] == type)
                    {
                        tempList.Add(fileItem.FullName);
                        Debug.Log(fileItem.FullName);
                    }
                }
            }
            //遍历文件夹
            foreach (DirectoryInfo NextFolder in dirInfo)
            {
                ForeachFile(NextFolder.FullName, type, action);
            }
        }
        catch (Exception e)
        {
            Debug.Log(e);
        }
    }

    IEnumerator IEForeachFile(string filePathByForeach, Action<List<string>> action)
    {
        DirectoryInfo theFolder = new DirectoryInfo(filePathByForeach);
        DirectoryInfo[] dirInfo = theFolder.GetDirectories();//获取所在目录的文件夹
        FileInfo[] file = theFolder.GetFiles();//获取所在目录的文件
        foreach (FileInfo fileItem in file) //遍历文件
        {
            yield return new WaitForEndOfFrame();
            Debug.Log(fileItem.FullName);
        }
        //遍历文件夹
        foreach (DirectoryInfo NextFolder in dirInfo)
        {
            ForeachFile(NextFolder.FullName, action);
        }
    }

    /// <summary>
    /// 查找文件夹下所有文件
    /// </summary>
    /// <param name="filePathByForeach"></param>
    /// <returns></returns>
    public static void ForeachFile(string filePathByForeach, Action<List<string>> action)
    {
        List<string> tempList = new List<string>();
        try
        {
            DirectoryInfo theFolder = new DirectoryInfo(filePathByForeach);
            DirectoryInfo[] dirInfo = theFolder.GetDirectories();//获取所在目录的文件夹
            FileInfo[] file = theFolder.GetFiles();//获取所在目录的文件
            foreach (FileInfo fileItem in file) //遍历文件
            {
                tempList.Add(fileItem.FullName);
                Debug.Log(fileItem.FullName);
            }
            //遍历文件夹
            foreach (DirectoryInfo NextFolder in dirInfo)
            {
                ForeachFile(NextFolder.FullName,action);
            }
        }
        catch (Exception e)
        {
            Debug.Log(e);
        }
    }

    /// <summary>
    /// 寻找或者创建文件夹
    /// </summary>
    /// <param name="Path"></param>
    public static void FindOrCreateFile(string Path)
    {
        if (!Directory.Exists(Path))
        {
            Directory.CreateDirectory(Path);
        }
    }

    /// <summary>
    /// 直接把可序列化对象转换成
    /// </summary>
    /// <param name="json"></param>
    /// <param name="path"></param>
    public static void SaveJsonToFile(object json,string path)
    {
        string jsondata = JsonUtility.ToJson(json);
        string jsonFilePath = Application.dataPath + "/../JsonFile";
        FindOrCreateFile(jsonFilePath);
        File.Create(jsonFilePath + "/GameData.josn");

    }

    /// <summary>
    /// 先读取json文件 然后解析json 返回解析后的类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="path"></param>
    /// <returns></returns>
    public static T ReadJsonFile<T>(string path)
    {
        string jsondata = ReadTxtToString(path);
        T t = JsonUtility.FromJson<T>(jsondata);
        return t;
    }
}
